#include "CtrlConvData.h"
#include "CAppCtx.h"
#include "GenOpt.h"
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QIcon>
#include <QStandardItemModel>
#include <QTextStream>
#include <QThread>
#include <qtmetamacros.h>
#include "CAppCtx.h"


int CThreadConv::ConvFormat(QString file, QString outfile) {
  QString FFMpeg = CAppCtx::instance()->GetFFMpegPath();
  QString command = FFMpeg + " -i " + file + " -c copy -y " + outfile;
  int result = std::system(command.toStdString().c_str());
  return result;
}

int CThreadConv::SaveRadarFile(QString file_name, SEI_MAP &data) {
  QFile file(file_name);
  if (!file.open(QIODevice::WriteOnly)) {
    return -1;
  }

  auto it = data.begin();
  for (; it != data.end(); it++) {
    int size = it->second.size();
    unsigned char *pdata = (unsigned char *)it->second.data();
    if (pdata[0] != 0x5a) {
      continue;
    }
    int len = (int)(pdata[4]) << 8 | pdata[3];
    int amp = (int)(pdata[6]) << 8 | pdata[5];
    QByteArray data;
    data.append(it->first);
    data.append(len);
    data.append(amp);
    file.write(data);
  }
  file.close();
  return 0;
}

void CThreadConv::run() {
  int index = 0;
  int ret = 0;
  int proc = 0;
  for (int index = 0; index < file_list_.size(); index++) {
    sei_map_.clear();
    QString cur_file = file_list_.at(index);
    emit setText(QString("正在处理%1/%2个文件:%3")
                     .arg(index + 1)
                     .arg(file_list_.size())
                     .arg(file_list_.at(index)));
    emit setText("正在转换格式...");
    QString file_name = CGenOpt::GetFileNameFromPath(cur_file);
    QString file_output = folder_output_ + "/" + file_name + ".mp4";
    ret = ConvFormat(cur_file, file_output);
    if (ret == 0) {
      emit setText("文件格式转换成功...");
    } else {
      emit setText("文件格式转换失败...");
    }
    emit setText("正在从视频文件中获取雷达数据...");
    ret = CMediaFile::GetRadarDataInSEI(file_output.toStdString().c_str(),
                                        sei_map_);
    if (sei_map_.size() != 0) {
      emit setText("获得雷达数据成功...");
    } else {
      emit setText("获得雷达数据失败...");
    }
    emit setText("正在保存雷达数据...");
    QString file_radar = folder_output_ + "/" + file_name + ".csv";
    ret = CMediaFile::SaveRadarDatatoFile(file_radar.toStdString().c_str(),
                                          sei_map_);
    if (ret == 0) {
      emit setText(
          QString("保存雷达数据成功, 共%1个雷达数据...").arg(sei_map_.size()));
    } else {
      emit setText("保存雷达数据失败...");
    }
    proc = (index + 1) * 100 / file_list_.size();
    if (proc != 100) {
      emit finished(proc);
    }
    if (stop_) {
      break;
    }
  }
  emit finished(100);
}

CtrlConvData::CtrlConvData(QWidget *parent) {
  ui.setupUi(this);
  OnInitWindow();
}

CtrlConvData::~CtrlConvData() {
  if (thread_conv_) {
    thread_conv_->quit();
    delete thread_conv_;
  }
}

void CtrlConvData::AddMsg(QString msg) {
  QListWidgetItem *item = new QListWidgetItem(msg, ui.listWidgetMsg);
  ui.listWidgetMsg->addItem(item);
  ui.listWidgetMsg->setCurrentRow(ui.listWidgetMsg->count() - 1);
}

void CtrlConvData::OnInitWindow() {
  setWindowTitle("视频数据转换");
  setWindowIcon(QIcon(":/ICON/icon_convert.png"));
  ui.pbStop->setEnabled(false);
  ui.processBarConv->setVisible(false);
  thread_conv_ = new CThreadConv(this);
  QObject::connect(thread_conv_, &CThreadConv::setText, this,
                   &CtrlConvData::AddMsg);
  QObject::connect(thread_conv_, &CThreadConv::finished, this,
                   &CtrlConvData::SetProcess);
}

void CtrlConvData::on_pbOutputBrowse_clicked() {
  QString file_path = QFileDialog::getExistingDirectory(
      this, "选择视频文件路径", "C:/", QFileDialog::DontResolveSymlinks);
  ui.leOutputFolder->setText(file_path);
  folder_output_ = file_path;
  AddMsg(QString("输出文件加配置为%1").arg(folder_output_));
}

void CtrlConvData::on_pbInputBrowse_clicked() {
  QString file_path = QFileDialog::getExistingDirectory(
      this, "选择视频文件路径", "C:/", QFileDialog::DontResolveSymlinks);
  ui.leInputFolder->setText(file_path);
  folder_input_ = file_path;
  AddMsg(QString("输入文件夹配置为%1").arg(folder_input_));
  file_list_.clear();
  CGenOpt::SearchAllFileInPath(file_path, file_list_);
  if (file_list_.count() == 0) {
    AddMsg(QString("输入路径中未找到任何视频文件"));
    return;
  }
  AddMsg(QString("输入路径中找到%1个视频文件").arg(file_list_.count()));
  ui.listWidgetFile->clear();
  ui.listWidgetFile->addItems(file_list_);
}

int CtrlConvData::SetProcess(int proc) {
  ui.processBarConv->setValue(proc);
  if (proc == 100) {
    ui.pbInputBrowse->setEnabled(true);
    ui.pbOutputBrowse->setEnabled(true);
    ui.pbStart->setEnabled(true);
    ui.pbStop->setEnabled(false);
    ui.processBarConv->setVisible(false);
    AddMsg(QString("数据格式转换完成!"));
  }
  return 0;
}

int CtrlConvData::Start() {
  thread_conv_->SetFileList(file_list_);
  thread_conv_->SetOutputFolder(folder_output_);
  thread_conv_->SetStop(false);
  thread_conv_->start();
  return 0;
}

void CtrlConvData::on_pbStart_clicked() {
  if (folder_input_.size() == 0) {
    AddMsg(QString("没有选择输入文件夹!"));
    return;
  }
  if (file_list_.size() == 0) {
    AddMsg(QString("路径中没有视频文件!"));
    return;
  }
  if (folder_output_.size() == 0) {
    AddMsg(QString("没有选择输出文件夹!"));
    return;
  }
  if (folder_output_ == folder_input_) {
    AddMsg(QString("输入文件夹和输出文件夹不能相同!"));
    return;
  }
  ui.pbInputBrowse->setEnabled(false);
  ui.pbOutputBrowse->setEnabled(false);
  ui.pbStart->setEnabled(false);
  ui.pbStop->setEnabled(true);
  ui.processBarConv->setVisible(true);
  ui.processBarConv->setRange(0, 100);
  ui.processBarConv->setValue(0);
  Start();
}
void CtrlConvData::on_pbStop_clicked() {
  AddMsg(QString("正在停止..."));
  thread_conv_->SetStop(true);
  thread_conv_->quit();
}
